﻿using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;
using System.Collections.Generic;

namespace 自动分享工具
{
    public partial class IETempFile
    {

        #region 引入dll

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct INTERNET_CACHE_ENTRY_INFO
        {
            public int dwStructSize;
            public IntPtr lpszSourceUrlName;
            public IntPtr lpszLocalFileName;
            public int CacheEntryType;
            public int dwUseCount;
            public int dwHitRate;
            public int dwSizeLow;
            public int dwSizeHigh;
            public FILETIME LastModifiedTime;
            public FILETIME ExpireTime;
            public FILETIME LastAccessTime;
            public FILETIME LastSyncTime;
            public IntPtr lpHeaderInfo;
            public int dwHeaderInfoSize;
            public IntPtr lpszFileExtension;
            public int dwExemptDelta;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct SYSTEMTIME
        {
            public short wYear;
            public short wMonth;
            public short wDayOfWeek;
            public short wDay;
            public short wHour;
            public short wMinute;
            public short wSecond;
            public short wMilliseconds;
        }

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int FileTimeToSystemTime(
        IntPtr lpFileTime,
        IntPtr lpSystemTime);

        [DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr FindFirstUrlCacheEntry(
        [MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,
        IntPtr lpFirstCacheEntryInfo,
        ref int lpdwFirstCacheEntryInfoBufferSize);

        [DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool FindNextUrlCacheEntry(
        IntPtr hEnumHandle,
        IntPtr lpNextCacheEntryInfo,
        ref int lpdwNextCacheEntryInfoBufferSize);

        [DllImport("wininet.dll")]
        public static extern bool FindCloseUrlCache(IntPtr hEnumHandle);

        const int ERROR_NO_MORE_ITEMS = 259;

        #endregion

        #region FileTimeToSystemTime

        private string FILETIMEtoDataTime(FILETIME time)
        {
            IntPtr filetime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FILETIME)));
            IntPtr systime = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SYSTEMTIME)));
            Marshal.StructureToPtr(time, filetime, true);
            FileTimeToSystemTime(filetime, systime);
            SYSTEMTIME st = (SYSTEMTIME)Marshal.PtrToStructure(systime, typeof(SYSTEMTIME));
            string Time = st.wYear.ToString() + "." + st.wMonth.ToString() + "." + st.wDay.ToString() + "." + st.wHour.ToString() + "." + st.wMinute.ToString() + "." + st.wSecond.ToString();
            return Time;
        }

        #endregion

        #region 加载数据
        public List<string> SearchTempFile(string atomString)
        {

            int nNeeded = 0, nBufSize;
            IntPtr buf;
            INTERNET_CACHE_ENTRY_INFO CacheItem;
            IntPtr hEnum;
            bool r;
            List<string> tempFileName = new List<string>();

            FindFirstUrlCacheEntry(null, IntPtr.Zero, ref nNeeded);

            if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                return null;

            nBufSize = nNeeded;
            buf = Marshal.AllocHGlobal(nBufSize);
            hEnum = FindFirstUrlCacheEntry(null, buf, ref nNeeded);
            while (true)
            {
                CacheItem = (INTERNET_CACHE_ENTRY_INFO)Marshal.PtrToStructure(buf, typeof(INTERNET_CACHE_ENTRY_INFO));

                string modifiedTime = FILETIMEtoDataTime(CacheItem.LastModifiedTime);
                string expireTime = FILETIMEtoDataTime(CacheItem.ExpireTime);
                string accessTime = FILETIMEtoDataTime(CacheItem.LastAccessTime);
                string syncTime = FILETIMEtoDataTime(CacheItem.LastSyncTime);

                #region 获得数据，存入数据库
                try
                {

                    //此處遍歷CacheItem即可 
                    //例如 
                    string s = Marshal.PtrToStringAuto(CacheItem.lpszSourceUrlName);
                    string s1 = atomString.Trim();
                    if (-1 != s.IndexOf(s1))
                    {
                        tempFileName.Add(Marshal.PtrToStringAuto(CacheItem.lpszLocalFileName));
                        //return tempFileName;
                    }
                    //可以获取CacheItem的本地文件路径
                    //这里如何把文件拷贝到另外一个文件夹中去，普通的文件拷贝好像不行

                }
                catch (Exception ex)
                {
                    //異常處理 
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
                #endregion

                //s = Marshal.PtrToStringAuto(CacheItem.lpszSourceUrlName);

                nNeeded = nBufSize;
                r = FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);

                if (!r && Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
                    break;

                if (!r && nNeeded > nBufSize)
                {
                    nBufSize = nNeeded;
                    buf = Marshal.ReAllocHGlobal(buf, (IntPtr)nBufSize);
                    FindNextUrlCacheEntry(hEnum, buf, ref nNeeded);
                }
            }



            MessageBox.Show("系统数据加载完毕！");
            Marshal.FreeHGlobal(buf);
            return tempFileName;
            //return null;
        }

        /// <summary>
        /// 删除指定的ie临时文件，不过现在不好使
        /// </summary>
        /// <param name="tempFiles"></param>
        /// <returns></returns>
        public bool RemoveTempFile(List<string> tempFiles)
        {
            try
            {
                foreach (string tempFile in tempFiles)
                {
                    if (File.Exists(tempFile))
                    {
                        File.Delete(tempFile);
                    }
                }
                return true;
            }
            catch 
            {
                return false;
            }
        }

        #endregion
    }
}